package com.sp.reflection;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 演示通过反射获取类的结构信息
 */
public class ReflectionUtils {

    //第一组方法API
    @Test
    public void api_01() throws ClassNotFoundException, NoSuchMethodException {

        //得到Class对象
        Class<?> personCls = Class.forName("com.sp.reflection.Person");
        //获取全类名
        System.out.println(personCls.getName());
        //getSimpleName: 获取简单类名
        System.out.println(personCls.getSimpleName());//Person
        //getFields: 获取所有的public修饰的属性, 包含本类以及父类的
        Field[] fields = personCls.getFields();
        for (Field field : fields) {
            System.out.println("本类以及父类的属性 = " + field.getName());
        }
        //getDeclaredFields: 获取本类中所有属性
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性 = " + declaredField);
        }
        //getMethods: 获取所有的public修饰的方法, 包含本类以及父类的
        Method[] methods = personCls.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的方法 = " + method.getName());
        }
        //getDeclaredMethods: 获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法 = " + declaredMethod.getName());
        }
        //getConstructors: 获取所有public修饰的构造器, 包含本类
        Constructor<?>[] constructors = personCls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("本类的构造器(public修饰的) = " + constructor);
        }
        //getDeclaredConstructors: 获取本类所有的构造器
        Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类中所有构造器 = " + declaredConstructor);
        }
        //getPackage: 以Package形式返回 包信息
        System.out.println(personCls.getPackage());
        //getSuperClass: 以Class形式返回父类信息
        Class<?> superclass = personCls.getSuperclass();
        System.out.println("父类的class对象 = " + superclass);
        //getInterfaces: 以class[] 形式返回接口信息
        Class<?>[] interfaces = personCls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("接口信息 = " + anInterface);
        }
        //getAnnotations: 以Annotations[]形式返回注解信息
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息 = " + annotation);
        }

    }

    @Test
    public void api_02() throws ClassNotFoundException, NoSuchMethodException {
        //得到Class对象
        Class<?> personCls = Class.forName("com.sp.reflection.Person");
        //getDeclaredFields: 获取本类中所有属性
        //规定 说明: 默认修饰符是0, public 是1, private是2, protected 是4, static 是8, final 是16
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性 = " + declaredField.getName()
                    + " 该属性的修饰符值 = " + declaredField.getModifiers()
                    + " 该属性的类型 = " + declaredField.getType());
        }

        //getDeclaredMethods: 获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法 = " + declaredMethod.getName()
                    + " 该方法的修饰符值 = " + declaredMethod.getModifiers()
                    + " 该方法的返回类型 = " + declaredMethod.getReturnType());

            //输出当前这个方法的形参数组情况
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该方法的形参类型 = " + parameterType);
            }
        }

        //getDeclaredConstructors: 获取本类中所有构造器
        Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("==================");
            System.out.println("本类中所有构造器 = " + declaredConstructor.getName());

            Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该构造器的形参类型 = " + parameterType);
            }
        }

    }
}


class A {
    public String hobby;
    public void hi() {

    }
    public A() {

    }
    public A(String name) {}

}

interface IA {

}

interface IB {

}

@Deprecated
class Person extends A implements IA, IB {
    //各种访问权限的属性
    public String name;
    protected static int age;
    String job;
    private double sal;

    //各种构造器
    public Person() {

    }
    public Person(String name) {

    }
    //私有
    private Person(String name, int age) {

    }

    //方法
    public void m1(String name, int age, double sal) {

    }
    protected String m2() {
        return null;
    }
    void m3() {

    }
    private void m4() {

    }

}